package com.qingcloud.adminbackend.controller;


import cn.hutool.core.codec.Base64;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.mail.MailUtil;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.teautil.models.RuntimeOptions;
import com.anji.captcha.model.common.ResponseModel;
import com.anji.captcha.service.CaptchaService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.qingcloud.adminbackend.anno.CloudApi;
import com.qingcloud.adminbackend.base.AjaxResult;
import com.qingcloud.adminbackend.config.RedisUtil;
import com.qingcloud.adminbackend.entity.app.AppShare;
import com.qingcloud.adminbackend.entity.user.SysUser;
import com.qingcloud.adminbackend.pojo.cloud.CloudApiRequest;
import com.qingcloud.adminbackend.service.IAppService;
import com.qingcloud.adminbackend.service.ISysOrderService;
import com.qingcloud.adminbackend.service.ISysOrgService;
import com.qingcloud.adminbackend.service.ISysUserService;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 云平台注册相关接口
 */
@RestController
@RequestMapping("/cloud")
public class CloudRegisterController {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private CaptchaService captchaService;

    @Resource
    private ISysUserService sysUserService;

    @Resource
    private ISysOrgService sysOrgService;

    @Resource
    private ISysOrderService sysOrderService;

    @Resource
    private IAppService appService;

    //短时间存储，用户重复发送检查
    private static final String VERIFY_SHORT_PREFIX = "qingcloud:register:verify:short:";
    //长时间存储
    private static final String VERIFY_LONG_PREFIX = "qingcloud:register:verify:long:";

    public static final String VERIFY_HTML = """
            <html>
            <meta charset="utf-8">
            <body>
            <div id="contentDiv" onmouseover="getTop().stopPropagation(event);"
                 onclick="getTop().preSwapLink(event, 'html', 'ZC0004_vDfNJayMtMUuKGIAzzsWvc8');"
                 style="position:relative;font-size:14px;height:auto;padding:15px 15px 10px 15px;z-index:1;zoom:1;line-height:1.7;"
                 class="body">
                <div id="qm_con_body">
                    <div id="mailContentContainer" class="qmbox qm_con_body_content qqmail_webmail_only" style="opacity: 1;">
                        <style type="text/css">
                            .qmbox h1, .qmbox h2, .qmbox h3 {
                                color: #e11e1e;
                            }

                            .qmbox p {
                                padding: 0;
                                margin: 0;
                                color: #333;
                                font-size: 16px;
                            }

                            .qmbox hr {
                                background-color: #d9d9d9;
                                border: none;
                                height: 1px;
                            }

                            .qmbox .eo-link {
                                color: #0576b9;
                                text-decoration: none;
                                cursor: pointer;
                            }

                            .qmbox .eo-link:hover {
                                color: #3498db;
                            }

                            .qmbox .eo-link:hover {
                                text-decoration: underline;
                            }

                            .qmbox .eo-p-link {
                                display: block;
                                margin-top: 20px;
                                color: #009cff;
                                text-decoration: underline;
                            }

                            .qmbox .p-intro {
                                padding: 30px;
                            }

                            .qmbox .p-code {
                                padding: 0 30px 0 30px;
                            }

                            .qmbox .p-news {
                                padding: 0px 30px 30px 30px;
                            }
                        </style>
                        <div style="max-width:800px;padding-bottom:10px;margin:20px auto 0 auto;">
                            <table cellpadding="0" cellspacing="0"
                                   style="background-color: #fff;border-collapse: collapse; border:1px solid #e5e5e5;box-shadow: 0 10px 15px rgba(0, 0, 0, 0.05);text-align: left;width: 100%;font-size: 14px;border-spacing: 0;">
                                <tbody>
                                <tr style="background-color: #f8f8f8;">
                                    <td>
                                        <img style="padding: 15px 0 15px 30px;width:141px"
                                             src="https://www.xingyangtech.cn/health/qing.png">
                                    </td>
                                </tr>
                                <tr>
                                    <td class="p-intro">
                                        <h1 style="font-size: 26px; font-weight: bold;">验证您的邮箱地址</h1>
                                        <p style="line-height:1.75em;">感谢您使用 轻云科技. </p>
                                        <p style="line-height:1.75em;">若非本人操作请忽视此信息</p>
                                        <p style="line-height:1.75em;">请查收您的邮箱验证码，10分钟内有效，将它输入到 轻云科技
                                            的邮箱验证码输入框中:</p>

                                    </td>
                                </tr>
                                <tr>
                                    <td class="p-code">
                                        <p style="color: #253858;text-align:center;line-height:1.75em;background-color: #f2f2f2;min-width: 200px;margin: 0 auto;font-size: 28px;border-radius: 5px;border: 1px solid #d9d9d9;font-weight: bold;">
                                            {} </p>
                                    </td>
                                </tr>
                                <tr>
                                    <td class="p-intro">
                                        <p style="line-height:1.75em;">这一封邮件包括一些您的 轻云科技
                                            账号信息，请不要回复或转发它，以免带来不必要的信息泄露风险。 </p>
                                    </td>
                                </tr>
                                <tr>
                                    <td class="p-intro">
                                        <hr>
                                        <p style="text-align: center;line-height:1.75em; "> 轻云科技团队 </p>
                                    </td>
                                </tr>
                                </tbody>
                            </table>
                        </div>
                        <style type="text/css">
                            .qmbox style, .qmbox script, .qmbox head, .qmbox link, .qmbox meta {
                                display: none !important;
                            }
                        </style>
                    </div>
                </div><!-- -->
                <style>
                    #mailContentContainer .txt {
                        height: auto;
                    }
                </style>
            </div>
            </body>
            </html>
                        """;

    /**
     * 验证手机号是否正确
     */
    private static boolean validatePhoneNumber(String phoneNumber) {
        Pattern pattern = Pattern.compile("^[1][0-9]{10}$");
        Matcher matcher = pattern.matcher(phoneNumber);
        return matcher.matches();
    }

    @CloudApi
    @ApiOperation(value = "发送验证码接口", notes = "发送验证码接口")
    @PostMapping("/verify/send")
    public AjaxResult sendVerifyCode(@RequestBody CloudApiRequest.VerifySendParam param) throws Exception {
        if (Integer.valueOf(1).equals(param.getType())) {
            if (!validatePhoneNumber(param.getTarget())) {
                return AjaxResult.fail("手机号非法");
            }
        }
        //检查是否已经发送了
        Object redisValue = redisUtil.get(VERIFY_SHORT_PREFIX + param.getTarget());
        if (redisValue != null && StrUtil.isNotBlank(redisValue.toString())) {
            return AjaxResult.fail("发送验证码太频繁");
        }
        //检查滑动验证码
        ResponseModel response = captchaService.verification(param);
        if (!response.isSuccess()) {
            return AjaxResult.fail(response.getRepMsg());
        }
        //生成随机验证码
        String code = RandomUtil.randomNumbers(6);
        String mailContent = StrUtil.format(VERIFY_HTML, code);

        ThreadUtil.execute(() -> {
            if (Integer.valueOf(1).equals(param.getType())) {
                sendSms(param.getTarget(), code);
            } else {
                MailUtil.sendHtml(param.getTarget(), "轻云科技邮箱验证码", mailContent);
            }
        });
        //缓存已发送
        redisUtil.set(VERIFY_SHORT_PREFIX + param.getTarget(), code, 59);
        redisUtil.set(VERIFY_LONG_PREFIX + param.getTarget(), code, 600);
        logger.info("{} 验证码是 {}", param.getTarget(), code);
        return AjaxResult.success();
    }

    /**
     * 短信发送接口
     */
    private void sendSms(String phone, String code) {
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
                // 必填，您的 AccessKey ID
                .setAccessKeyId("LTAI5tKbgRa2zhLL3sC8pwXh")
                // 必填，您的 AccessKey Secret
                .setAccessKeySecret("6DExpTXH8NZKxKcaVATr4ThpjD7ENu");
        // Endpoint 请参考 https://api.aliyun.com/product/Dysmsapi
        config.endpoint = "dysmsapi.aliyuncs.com";
        try {
            JSONObject codeObject = new JSONObject();
            codeObject.put("code", code);
            com.aliyun.dysmsapi20170525.Client client = new Client(config);
            com.aliyun.dysmsapi20170525.models.SendSmsRequest sendSmsRequest = new com.aliyun.dysmsapi20170525.models.SendSmsRequest()
                    .setPhoneNumbers(phone)
                    .setTemplateParam(codeObject.toJSONString())
                    .setTemplateCode("SMS_465320827")
                    .setSignName("轻云科技");
            // 复制代码运行请自行打印 API 的返回值
            client.sendSmsWithOptions(sendSmsRequest, new RuntimeOptions());
        } catch (Exception error) {
            logger.error(error.getMessage(), error);
        }
    }

    @CloudApi
    @ApiOperation(value = "检查手机号或者邮箱是否已经存在", notes = "检查手机号或者邮箱是否已经存在")
    @PostMapping("/check/username")
    public AjaxResult checkUserName(@RequestBody CloudApiRequest.VerifySendParam param) throws UnsupportedEncodingException {
        long count = 0;
        if (Integer.valueOf(1).equals(param.getType())) {
            //检查手机号
            count = sysUserService.count(Wrappers.<SysUser>lambdaQuery()
                    .eq(SysUser::getMobileno, param.getTarget())
                    .eq(SysUser::getDeleteFlag, 0));
        } else {
            //检查邮箱
            count = sysUserService.count(Wrappers.<SysUser>lambdaQuery()
                    .eq(SysUser::getUserName, param.getTarget())
                    .eq(SysUser::getDeleteFlag, 0));
            if (count <= 0) {
                count = sysUserService.count(Wrappers.<SysUser>lambdaQuery()
                        .eq(SysUser::getWorkEmail, param.getTarget())
                        .eq(SysUser::getDeleteFlag, 0));
            }
        }
        if (count > 0) {
            return AjaxResult.fail(param.getTarget() + "已注册，可直接登录");
        }
        return AjaxResult.success();
    }

    @CloudApi
    @ApiOperation(value = "检查企业名称是否存在", notes = "检查企业名称是否存在")
    @PostMapping("/check/org")
    public AjaxResult checkOrgName(@Valid @RequestBody CloudApiRequest.CheckOrgParam param) throws UnsupportedEncodingException {
        return AjaxResult.ok(sysOrgService.countOrgByName(param.getCompany()));
    }

    @CloudApi
    @ApiOperation(value = "用户注册接口", notes = "用户注册接口")
    @PostMapping("/register")
    public AjaxResult register(@Valid @RequestBody CloudApiRequest.RegisterParam param) {
        //检查验证码
        Object redisValue = redisUtil.get(VERIFY_LONG_PREFIX + param.getPhone());
        if (Objects.isNull(redisValue) || !redisValue.toString().equals(param.getVerifyCode())) {
            return AjaxResult.fail("验证码不正确");
        }
        if (StrUtil.isNotBlank(param.getShareKey())) {
            //从应用分享来的，检查是否到期
            AppShare appShare = appService.findAppShare(param.getShareKey());
            if (Objects.isNull(appShare)) {
                return AjaxResult.fail("未找到邀请信息");
            }
            if ((System.currentTimeMillis() - appShare.getCreateTime().getTime()) > 60 * 60 * 1000) {
                return AjaxResult.fail("邀请链接已过期");
            }
            param.setAppId(appShare.getAppId());
            param.setGroupId(appShare.getGroupId());
            param.setRoleId(appShare.getRoleId());
        }
        //创建组织
        String orgId = param.getOrgId();
        if (StrUtil.isBlank(orgId)) {
            //新建组织注册
            orgId = sysOrgService.registerOrg(param.getCompany());
        }
        //创建订单
        String orderId = sysOrderService.registerOrder(param.getCompany(), orgId);
        //解密密码参数
        String password = Base64.decodeStr(param.getPassword(), StandardCharsets.UTF_8);
        param.setPassword(password);
        //创建用户
        String userId = sysUserService.register(param, orgId, orderId);
        return AjaxResult.ok(userId);
    }

    @CloudApi
    @ApiOperation(value = "用户找回密码", notes = "用户找回密码")
    @PostMapping("/password")
    public AjaxResult findPassword(@Valid @RequestBody CloudApiRequest.FindPwdParam param) {
        //检查验证码
        Object redisValue = redisUtil.get(VERIFY_LONG_PREFIX + param.getEmail());
        if (Objects.isNull(redisValue) || !redisValue.toString().equals(param.getVerifyCode())) {
            return AjaxResult.fail("验证码不正确");
        }
        //解密密码参数
        String password = Base64.decodeStr(param.getPassword(), StandardCharsets.UTF_8);
        String userId = sysUserService.findPassword(param.getEmail(), password);
        return AjaxResult.ok(userId);
    }

    @CloudApi
    @ApiOperation(value = "轻云修改用户信息", notes = "轻云修改用户信息")
    @PostMapping("/user/modify")
    public AjaxResult modifyUser(@Valid @RequestBody CloudApiRequest.ModifyParam param) {
        sysUserService.cloudModifyUser(param.getUserId(), param.getFullName(), param.getPhone());
        return AjaxResult.ok();
    }

}

